package martian.m4gic.network.smartfox.core
{
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.IExternalizable;
	
	import it.gotoandplay.smartfoxserver.SFSEvent;
	import it.gotoandplay.smartfoxserver.SmartFoxClient;
	import it.gotoandplay.smartfoxserver.data.Room;
	import it.gotoandplay.smartfoxserver.data.User;
	
	import martian.m4gic.tools.B64;
	
	public class Fox extends EventDispatcher
	{
		static public const CONNECTED:String = "onConnect";
		static public const DISCONNECTED:String = "onDisconnect";
		static public const DATA:String = "onData";
		
		static public const FRIEND_CONNECTED:String = "onFriendConnect";
		static public const FRIEND_DISCONNECTED:String = "onFriendDisconnected";
		static public const FRIEND_UPDATE:String = "onFriendUpdate";
		
		static public const ERROR:String = "error";
		
		
		
		
		static public var SERVER:String = "";
		static public var PORT:int = -1;
		static public var ZONE:String = "";
		static public var ROOM:String = "";
		
		
		
		
		
		private var client:SmartFoxClient;
			public function get id():int { return client.myUserId; }
			public function get name():String { return client.myUserName; }
			public function get room():Room { return client.getRoom(client.activeRoomId); }
			public function get user():User { return room.getUser(id); }
			
		private var properties:Dictionary = new Dictionary();
			public function get(property:*):* { return properties[property]; }
			public function set(data:Object):void
			{
				for(var property:* in data) { properties[String(property)] = data[property]; }
				client.setUserVariables(data);
			}
			
			
			
			
			
		private var username:String = "";
		private var userpass:String = "";
		
		public var handler:Handler = null;
		public var data:Object = null;
		
		
		public function Fox(transcoder:Handler = null, debug:Boolean = false)
		{
			if (!Wire.client) { Wire.client = this; }
			
			handler = transcoder != null ? transcoder : new Serializer();
			
			client = new SmartFoxClient(debug);
				client.addEventListener(SFSEvent.onConnection, onconnect);
				client.addEventListener(SFSEvent.onLogin, onlogin);
				client.addEventListener(SFSEvent.onRoomListUpdate, onlist);
				client.addEventListener(SFSEvent.onJoinRoom, onroom);
				
				client.addEventListener(SFSEvent.onPublicMessage, onmessage);
				client.addEventListener(SFSEvent.onPrivateMessage, onmessage);
				
				client.addEventListener(SFSEvent.onUserEnterRoom, onuserenter);
				client.addEventListener(SFSEvent.onUserLeaveRoom, onuserleave);
				client.addEventListener(SFSEvent.onUserVariablesUpdate, onuserupdate);
				
				client.addEventListener(SFSEvent.onConnectionLost, ondisconnect);
		}

		public function login(user:String, pass:String = ""):void
		{
			username = user;
			userpass = pass;
			
			if (!client.isConnected)	{ client.connect(SERVER, PORT); }
			else { onconnect(null); }
		}
		
		public function notice(userid:int, object:Object):void
		{
			client.sendPrivateMessage(handler.encode(object), userid);
		}
		
		public function broadcast(object:Object):void
		{
			client.sendPublicMessage(handler.encode(object));
		}
		
		private function onconnect(e:SFSEvent):void { client.login(ZONE, username, userpass); }
		private function onlogin(e:SFSEvent):void
		{ 
			if (e.params.success) { client.getRoomList(); }
			else { dispatchEvent(new Event(ERROR)); }
		}
		
		private function onlist(e:SFSEvent):void { client.joinRoom(ROOM); }
		private function onroom(e:SFSEvent):void
		{
			data = e.params;
			dispatchEvent(new Event(CONNECTED));
		}
		
		private function onmessage(e:SFSEvent):void
		{
			e.params.message = handler.decode(e.params.message);
			data = e.params;
			
			dispatchEvent(new Event(DATA));
		}
		
		private function ondisconnect(e:SFSEvent):void
		{
			data = e.params;
			dispatchEvent(new Event(DISCONNECTED));
		}
		
		private function onuserenter(e:SFSEvent):void
		{
			data = e.params;
			dispatchEvent(new Event(FRIEND_CONNECTED));
		}
		
		private function onuserleave(e:SFSEvent):void
		{
			data = e.params;
			dispatchEvent(new Event(FRIEND_DISCONNECTED));
		}
		
		private function onuserupdate(e:SFSEvent):void
		{
			data = e.params;
			dispatchEvent(new Event(FRIEND_UPDATE));
		}
		
	}
}